#pragma once
#include <iostream>
#include <functional>
// OS
#include <pthread.h>
#include <unistd.h>

namespace ThreadMoudle
{
    class threadData
    {
    public:
        threadData(std::string name, pthread_mutex_t *lock)
            : _name(name), _lock(lock)
        {
        }

    public:
        std::string _name;
        pthread_mutex_t *_lock;
    };

    // typedef void (*func_t)(threadData *); // 线程运行函数类型
    //  typedef std::function<void()> func_t;
    using func_t = std::function<void()>;

    class myThread
    {
    public:
        void Execute()
        {
            std::cout << "new mythread running... name:" << _name << std::endl;
            _isrunning = true;
            _func(); //_func(_td);
            _isrunning = false;
        }

    public:
        myThread(const std::string name, func_t func)//, threadData *td)
            : _name(name), _func(func)  //, _td(td)
        {
            std::cout << "new myThread create success, name:" << name << std::endl;
        }
        static void *ThreadRoutine(void *args)
        {
            //((myThread*)args)->_func(((myThread*)args)->_name);//方法一
            myThread *self = static_cast<myThread *>(args);
            self->Execute(); // self->_func(self->_name);
            return nullptr;
        }
        bool Start()
        {
            int n = pthread_create(&_tid, nullptr, ThreadRoutine, (void *)this);
            if (n != 0)
            {
                perror("pthread_create fail");
                return false;
            }
            else
            {
                std::cout << "pthread_create success--" << _name << std::endl;
            }
            return true;
        }
        void Join()
        {
            // void *result = nullptr;
            int n = pthread_join(_tid, nullptr);
            //std::cout << n << std::endl;
            if (n != 0)
            {
                // std::cout << "pthread_join fail, Thread name:" <<  _name << std::endl;
                perror("pthread_join fail");
            }
            else
            {
                std::cout << "pthread_join wait new myThread success, Thread name:" << _name << std::endl;
            }
            //delete _td; // 释放
        }
        std::string Stat()
        {
            if (_isrunning)
                return "running";
            else
                return "sleep";
        }
        void Stop()
        {
            if (_isrunning)
            {
                pthread_cancel(_tid); // 取消指定线程
                _isrunning = false;
                std::cout << _name << " stop" << std::endl;
            }
        }
        std::string Name()
        {
            return _name;
        }
        ~myThread()
        {
        }


    private:
        const std::string _name;
        pthread_t _tid;
        func_t _func;
        bool _isrunning;
        //threadData *_td;
        // threadData& _td;
        //  注意：生命周期：确保 threadData 对象的生命周期长于这个类的实例。否则，_td 引用的对象可能会在 threadData 对象被销毁后变成悬空引用。
        //  线程安全：如果 threadData 被多个线程访问，确保它的访问是线程安全的。
        //  引用的合法性：_td 必须在构造函数中被初始化，因为引用成员不能在定义后再被重新赋值。
        //  如果这些条件满足，这种设计是可以的。
    };
};
